package Databaus2;

import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;

import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.custom.CCombo;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.jface.action.Action;
import org.eclipse.swt.widgets.TableColumn;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.eclipse.swt.custom.StackLayout;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.swt.widgets.Display;

public class GUI extends ApplicationWindow {
	private ArrayList<Pallet> palletList;
	private ArrayList<Material> materialList;
	private Database db;
	private Table palletTable;
	private Table materialTable;
	private Text pIDInput;
	private Text oIDInput;
	private Text startDateInput;
	private Text endDateInput;
	private Text customerNameInput;
	private Text amountInput_2;
	private Text amountInput_1;
	private Action action;
	private Action action_1;
	private Composite container;
	private Composite storagePane;
	private Composite materialPane;
	private final DateFormat DEFAULT_DATE = new SimpleDateFormat("yyyy-mm-dd");
	private final StackLayout layout = new StackLayout();

	/**
	 * Create the application window.
	 */
	public GUI() {
		super(null);
		createActions();
		addMenuBar();
		palletList = new ArrayList<Pallet>();
		db = new Database();
//		 if (db.openConnection("db14", "mNZdrk8gKZ"))
//		 System.out.println("Success");
//		 else
//		 System.out.println("Failed to connect");
		if (db.openConnection("root", "pass"))
			 System.out.println("Success");
			 else
			 System.out.println("Failed to connect");
	}

	/**
	 * Create contents of the application window. Contains of mainly 3
	 * composites.
	 * 
	 * @param parent
	 *            Main composite
	 */
	protected Control createContents(Composite parent) {
		container = new Composite(parent, SWT.NONE);
		container.setLayout(layout);

		// ------------ START storage tab
		storagePane = new Composite(container, SWT.NONE);

		palletTable = new Table(storagePane, SWT.BORDER | SWT.FULL_SELECTION);
		palletTable.setBounds(10, 0, 571, 177);
		palletTable.setHeaderVisible(true);
		palletTable.setLinesVisible(true);

		setStorageColumn();

		pIDInput = new Text(storagePane, SWT.BORDER);
		pIDInput.setBounds(10, 210, 87, 21);
		oIDInput = new Text(storagePane, SWT.BORDER);
		oIDInput.setBounds(103, 210, 87, 21);
		
		customerNameInput = new Text(storagePane, SWT.BORDER);
		customerNameInput.setText("All customers");
		customerNameInput.setBounds(382, 210, 82, 21);
		customerNameInput.addListener(SWT.FocusIn, new Listener() {
			public void handleEvent(Event arg0) {
				if (customerNameInput.getText().equals("All customers")) {
					customerNameInput.setText("");
				}

			}
		});

		startDateInput = new Text(storagePane, SWT.BORDER);
		startDateInput.setToolTipText("Format: YYYY-MM-DD");
		startDateInput.setText("YYYY-MM-DD");
		startDateInput.setBounds(196, 210, 87, 21);
		startDateInput.addListener(SWT.FocusIn, new Listener() {
			public void handleEvent(Event arg0) {
				if (startDateInput.getText().equals("YYYY-MM-DD")) {
					startDateInput.setText("");
				}

			}
		});
		endDateInput = new Text(storagePane, SWT.BORDER);
		endDateInput.setToolTipText("Format: YYYY-MM-DD");
		endDateInput.setText("YYYY-MM-DD");
		endDateInput.setBounds(289, 210, 87, 21);
		endDateInput.addListener(SWT.FocusIn, new Listener() {
			public void handleEvent(Event arg0) {
				if (endDateInput.getText().equals("YYYY-MM-DD")) {
					endDateInput.setText("");
				}

			}
		});

		CLabel lblPalletId = new CLabel(storagePane, SWT.NONE);
		lblPalletId.setBounds(10, 183, 61, 21);
		lblPalletId.setText("Pallet ID");

		CLabel lblOrderId = new CLabel(storagePane, SWT.NONE);
		lblOrderId.setBounds(103, 183, 61, 21);
		lblOrderId.setText("Order ID");

		CLabel lblstartDate = new CLabel(storagePane, SWT.NONE);
		lblstartDate.setBounds(196, 183, 61, 21);
		lblstartDate.setText("Start date");

		CLabel lblEndDate = new CLabel(storagePane, SWT.NONE);
		lblEndDate.setBounds(289, 183, 61, 21);
		lblEndDate.setText("End date");

		CLabel lblCookieName = new CLabel(storagePane, SWT.NONE);
		lblCookieName.setBounds(10, 237, 88, 21);
		lblCookieName.setText("Cookie name");

		CLabel lblCustomerName = new CLabel(storagePane, SWT.NONE);
		lblCustomerName.setBounds(382, 183, 102, 21);
		lblCustomerName.setText("Customer name");

		CLabel lblStatus = new CLabel(storagePane, SWT.NONE);
		lblStatus.setBounds(103, 237, 61, 21);
		lblStatus.setText("Status");

		final CCombo cookieNameSelector = new CCombo(storagePane, SWT.BORDER);
		cookieNameSelector.setText("All cookies");
		cookieNameSelector.setBounds(10, 264, 87, 21);
		String[] cookieList = getCookies();
		for (int i = 0; i < cookieList.length; i++) {
			cookieNameSelector.add(cookieList[i]);
		}
		cookieNameSelector.addListener(SWT.FocusIn, new Listener() {
			public void handleEvent(Event arg0) {
				if (cookieNameSelector.getText().equals("All cookies")) {
					cookieNameSelector.setText("");
				}

			}
		});

		final CCombo statusSelector = new CCombo(storagePane, SWT.BORDER);
		statusSelector.setText("All");
		statusSelector.setBounds(103, 264, 87, 21);
		statusSelector.add("All");
		statusSelector.add("Not blocked");
		statusSelector.add("Blocked");

		Button btnBlock = new Button(storagePane, SWT.NONE);
		btnBlock.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				TableItem[] block = palletTable.getItems();
				try {

					if (block[palletTable.getSelectionIndex()].getText(8)
							.equals("X")) {
						db.unblockPallet(Integer.parseInt(block[palletTable
								.getSelectionIndex()].getText(0)));
						block[palletTable.getSelectionIndex()].setText(8, "");

					} else {
						db.blockPallet(Integer.parseInt(block[palletTable
								.getSelectionIndex()].getText(0)));
						block[palletTable.getSelectionIndex()].setText(8, "X");
					}

				} catch (ArrayIndexOutOfBoundsException e5) {
					System.err.println("Selection error");
				}

				palletTable.redraw();

			}
		});
		btnBlock.setBounds(470, 208, 75, 25);
		btnBlock.setText("Block");

		Button btnSearch = new Button(storagePane, SWT.NONE);
		btnSearch.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				searchResults(cookieNameSelector.getText(),
						statusSelector.getText());
			}
		});
		btnSearch.setBounds(470, 260, 75, 25);
		btnSearch.setText("Search");

		ToolBar toolBar = new ToolBar(storagePane, SWT.FLAT | SWT.RIGHT);
		toolBar.setBounds(196, 262, 183, 23);

		ToolItem tltmShowStorage = new ToolItem(toolBar, SWT.NONE);
		tltmShowStorage.setToolTipText("View all pallets");
		tltmShowStorage.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				System.out.println("Storage stuff");
				palletList = db.getPallets();
				printPalletResults();
			}
		});
		tltmShowStorage.setText("Show storage");

		ToolItem tltmSimulateOrders = new ToolItem(toolBar, SWT.NONE);
		tltmSimulateOrders.setToolTipText("Simulate orders randomly");
		tltmSimulateOrders.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				System.out.println("orders");
				db.randomOrders();
				palletList = db.getPallets();
				printPalletResults();
			}
		});
		tltmSimulateOrders.setText("Simulate orders");

		// ------------ END

		// ------------ START material tab
		materialPane = new Composite(container, SWT.NONE);
		materialTable = new Table(materialPane, SWT.BORDER | SWT.FULL_SELECTION);
		materialTable.setBounds(10, 0, 291, 316);
		materialTable.setHeaderVisible(true);
		materialTable.setLinesVisible(true);

		setProductionColumn();

		amountInput_2 = new Text(materialPane, SWT.BORDER);
		amountInput_2.setBounds(417, 245, 138, 21);
		amountInput_1 = new Text(materialPane, SWT.BORDER);
		amountInput_1.setBounds(417, 84, 138, 21);

		CLabel lblOrderRawMaterials = new CLabel(materialPane, SWT.NONE);
		lblOrderRawMaterials.setBounds(375, 174, 117, 21);
		lblOrderRawMaterials.setText("Order ingredient");

		CLabel lblMaterialName = new CLabel(materialPane, SWT.NONE);
		lblMaterialName.setBounds(319, 218, 91, 21);
		lblMaterialName.setText("Ingredient:");

		CLabel lblAmount = new CLabel(materialPane, SWT.NONE);
		lblAmount.setBounds(329, 245, 61, 21);
		lblAmount.setText("Amount:");

		CLabel lblProducePallet = new CLabel(materialPane, SWT.NONE);
		lblProducePallet.setBounds(375, 10, 91, 21);
		lblProducePallet.setText("Produce pallet");

		final CLabel lblCookieName_1 = new CLabel(materialPane, SWT.NONE);
		lblCookieName_1.setBounds(319, 57, 81, 21);
		lblCookieName_1.setText("Cookie name:");

		CLabel lblAmount_1 = new CLabel(materialPane, SWT.NONE);
		lblAmount_1.setBounds(329, 84, 61, 21);
		lblAmount_1.setText("Amount:");

		final CLabel lblMessageField = new CLabel(materialPane, SWT.NONE);
		lblMessageField.setBounds(307, 126, 136, 21);
		lblMessageField.setText("");

		final CCombo cookieNameSelector_1 = new CCombo(materialPane, SWT.BORDER);
		cookieNameSelector_1.setBounds(417, 57, 138, 21);
		for (int i = 0; i < cookieList.length; i++) {
			cookieNameSelector_1.add(cookieList[i]);
		}

		final CCombo materialNameSelector = new CCombo(materialPane, SWT.BORDER);
		materialNameSelector.setBounds(417, 218, 138, 21);
		String[] materialList = getMaterials();
		for (int i = 0; i < materialList.length; i++) {
			materialNameSelector.add(materialList[i]);
		}

		final CLabel lblMessageField_1 = new CLabel(materialPane, SWT.NONE);
		lblMessageField_1.setBounds(307, 291, 136, 21);
		lblMessageField_1.setText("");

		Button btnProducePallet = new Button(materialPane, SWT.NONE);
		btnProducePallet.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				try {
					if (db.producePallet(cookieNameSelector_1.getText(),
							Integer.parseInt(amountInput_1.getText()))) {
						lblMessageField.setText("New pallet added.");
						printMaterialResults();
					} else {
						lblMessageField.setText("Not enough ingredients.");
					}

				} catch (NumberFormatException e1) {
					lblMessageField.setText("Not valid number.");

				} catch (IndexOutOfBoundsException e2) {
					lblMessageField.setText("Not valid cookie name.");
				} finally {
					removeTextTimer(Display.getDefault(), lblMessageField);
				}

			}
		});
		btnProducePallet.setBounds(449, 122, 91, 25);
		btnProducePallet.setText("Produce pallet");

		Button btnPlaceOrder = new Button(materialPane, SWT.NONE);
		btnPlaceOrder.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				try {

					if (db.addIngredient(materialNameSelector.getText(),
							Integer.parseInt(amountInput_2.getText()))) {
						lblMessageField_1.setText("New ingredients added.");
						printMaterialResults();
					} else {
						lblMessageField_1.setText("Error.");
					}

				} catch (NumberFormatException e1) {
					lblMessageField_1.setText("Not valid number.");
				} finally {
					removeTextTimer(Display.getDefault(), lblMessageField_1);
				}
			}
		});
		btnPlaceOrder.setBounds(449, 291, 91, 25);
		btnPlaceOrder.setText("Place an order");

		// ------------ END

		// -----------Do not touch
		Menu menu = new Menu(parent);
		parent.setMenu(menu);
		layout.topControl = storagePane;
		container.layout();
		return container;
	}

	/**
	 * Creates the actions.
	 */
	private void createActions() {
		action = new Action("Pallets") {
			public void run() {
				System.out.println("1st pressed");
				layout.topControl = storagePane;
				container.layout();
			}
		};
		action.setToolTipText("Pallets panel");
		{
			action_1 = new Action("Production") {
				public void run() {
					System.out.println("2nd pressed");
					printMaterialResults();
					layout.topControl = materialPane;
					container.layout();
				}
			};
			action_1.setToolTipText("Production panel");
		}
	}

	/**
	 * Create the menu manager.
	 * 
	 * @return the menu manager
	 */
	protected MenuManager createMenuManager() {
		MenuManager menuManager = new MenuManager("menu");
		menuManager.add(action);
		menuManager.add(action_1);
		return menuManager;
	}

	/**
	 * Configure the shell.
	 * 
	 * @param newShell
	 */
	protected void configureShell(Shell newShell) {
		super.configureShell(newShell);
		newShell.setText("Krusty Kookies");
	}

	/**
	 * Return the initial size of the window.
	 */
	protected Point getInitialSize() {
		return new Point(610, 410);
	}

	/**
	 * Parse a String to the format date.
	 * 
	 * @param date
	 *            String to be parsed
	 * @return Parsed string
	 * @throws ParseException
	 */
	private Date parseToDate(String date) throws ParseException {
		return DEFAULT_DATE.parse(date);
	}

	/**
	 * Displays all pallet results currently known.
	 */
	private void printPalletResults() {
		palletTable.removeAll();
		for (int i = 0; i < palletList.size(); i++) {
			TableItem item = new TableItem(palletTable, SWT.NONE);
			String[] temp = palletList.get(i).getAll();
			Order order = db.getOrder(palletList.get(i).getOID());
			if (palletList.get(i).getOID() != 0) {
				temp[4] = order.getDeliveryDate();
				temp[5] = order.isDelivered() ? "Y" : "N";
				temp[6] = order.getCustomerName();
			}
			else{
				temp[1] = "";
			}
			item.setText(temp);

		}
	}

	/**
	 * Displays all material results currently known.
	 */
	private void printMaterialResults() {
		materialTable.removeAll();
		materialList = db.getMaterials();
		for (int i = 0; i < materialList.size(); i++) {
			TableItem item = new TableItem(materialTable, SWT.NONE);
			String[] temp = materialList.get(i).getAll();
			item.setText(temp);
		}
	}

	/**
	 * Fetch available cookies.
	 * 
	 * @return String[] List of available cookies
	 */
	private String[] getCookies() {
		return db.getCookieList();
	}

	/**
	 * Fetch available ingredients.
	 * 
	 * @return String[] List of available ingredients
	 */
	private String[] getMaterials() {
		return db.getMaterialList();
	}

	/**
	 * Fetches all pallets matching the requirements and prints the result.
	 * 
	 * @param cookie
	 *            Name of the cookie from the select menu
	 * @param status
	 *            Status from the select menu
	 */
	private void searchResults(String cookie, String status) {
		String cookieName = cookie;
		String date1 = startDateInput.getText();
		String date2 = endDateInput.getText();
		String customer = customerNameInput.getText();
		String blocked = status;
		if (blocked.equals("Blocked")) {
			blocked = "true";
		} else if (blocked.equals("Not blocked")) {
			blocked = "false";
		}
		if(cookieName.equals("All cookies")){
			cookieName = "";
		}
		
		if(customer.equals("All customers")){
			customer = "";
		}
		int oID;
		int pID;

		try {
			pID = Integer.parseInt(pIDInput.getText());
		} catch (NumberFormatException e1) {
			System.err.println("Invalid pID");
			pID = 0;
		}
		try {
			oID = Integer.parseInt(oIDInput.getText());
		} catch (NumberFormatException e2) {
			System.err.println("Invalid oID");
			oID = 0;
		}

		try {
			parseToDate(date1);
		} catch (ParseException e3) {
			System.err.println("Invalid start date");
			date1 = "";
		}

		try {
			parseToDate(date2);
		} catch (ParseException e4) {
			System.err.println("Invalid end date");
			date2 = "";
		}

		System.out.println("cookiename:"+cookieName + " date1:" + date1 + " date2:" + date2 + " pid:" + pID
				+ " oid:" + oID + " customer:" + customer +" blocked:"+ blocked);
		palletList = db.search(cookieName, date1, date2, pID, oID, blocked,
				customer);
		printPalletResults();
	}

	/**
	 * Removes the given text after 4 seconds.
	 * 
	 * @param display
	 *            Display, for getting thread
	 * @param label
	 *            Which label to be removed
	 */
	private void removeTextTimer(final Display display, final CLabel label) {

		new Timer().schedule(new TimerTask() {
			@Override
			public void run() {
				// TODO Auto-generated method stub
				Display.getDefault().asyncExec(new Runnable() {
					@Override
					public void run() {
						// TODO Auto-generated method stub
						label.setText("");
					}
				});
			}
		}, 4000);
	}

	/**
	 * Sets all columns for the production tab.
	 */
	private void setProductionColumn() {

		TableColumn tblclmnCookie_1 = new TableColumn(materialTable, SWT.NONE);
		tblclmnCookie_1.setToolTipText("Name of the raw material");
		tblclmnCookie_1.setWidth(65);
		tblclmnCookie_1.setText("Material");

		TableColumn tblclmnAmount = new TableColumn(materialTable, SWT.NONE);
		tblclmnAmount.setToolTipText("Currently in stock");
		tblclmnAmount.setWidth(57);
		tblclmnAmount.setText("Amount");

		TableColumn tblclmnLastOrdered = new TableColumn(materialTable,
				SWT.NONE);
		tblclmnLastOrdered.setToolTipText("Date of the last order");
		tblclmnLastOrdered.setWidth(89);
		tblclmnLastOrdered.setText("Ordered last");

		TableColumn tblclmnSizeLastOrder = new TableColumn(materialTable,
				SWT.NONE);
		tblclmnSizeLastOrder.setToolTipText("Size of last order");
		tblclmnSizeLastOrder.setWidth(74);
		tblclmnSizeLastOrder.setText("Size");
	}

	/**
	 * Sets all columns for the storage tab.
	 */
	private void setStorageColumn() {

		TableColumn tblclmnPalletId = new TableColumn(palletTable, SWT.NONE);
		tblclmnPalletId.setToolTipText("ID of pallet");
		tblclmnPalletId.setWidth(55);
		tblclmnPalletId.setText("Pallet ID");

		TableColumn tblclmnOrderId = new TableColumn(palletTable, SWT.NONE);
		tblclmnOrderId.setToolTipText("ID of specific order");
		tblclmnOrderId.setWidth(57);
		tblclmnOrderId.setText("Order ID");

		TableColumn tblclmnCookie = new TableColumn(palletTable, SWT.NONE);
		tblclmnCookie.setToolTipText("Name of cookie");
		tblclmnCookie.setWidth(52);
		tblclmnCookie.setText("Cookie");

		TableColumn tblclmnBakingDate = new TableColumn(palletTable, SWT.NONE);
		tblclmnBakingDate.setToolTipText("Date when the cookie was baked");
		tblclmnBakingDate.setWidth(74);
		tblclmnBakingDate.setText("Baking date");

		TableColumn tblclmnDeliveryDate = new TableColumn(palletTable, SWT.NONE);
		tblclmnDeliveryDate.setToolTipText("Date of delivery");
		tblclmnDeliveryDate.setWidth(80);
		tblclmnDeliveryDate.setText("Delivery date");

		TableColumn tblclmnDelivered = new TableColumn(palletTable, SWT.NONE);
		tblclmnDelivered.setToolTipText("Delivery status");
		tblclmnDelivered.setWidth(62);
		tblclmnDelivered.setText("Delivered");

		TableColumn tblclmnCustomer = new TableColumn(palletTable, SWT.NONE);
		tblclmnCustomer.setToolTipText("Name of customer");
		tblclmnCustomer.setWidth(69);
		tblclmnCustomer.setText("Customer");

		TableColumn tblclmnLocation = new TableColumn(palletTable, SWT.NONE);
		tblclmnLocation.setToolTipText("Current location");
		tblclmnLocation.setWidth(60);
		tblclmnLocation.setText("Location");

		final TableColumn tblclmnBlocked = new TableColumn(palletTable,
				SWT.NONE);
		tblclmnBlocked.setToolTipText("Pallet status");
		tblclmnBlocked.setWidth(56);
		tblclmnBlocked.setText("Blocked");
	}
}
